/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package hybris;

import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.Random;

/**
 *
 * @author menderleit
 */
public class Intro extends DemoPart {

    private Random rnd;
    private Starfield sf;
    private int sfAlpha;
    private long sfTime;
    private int logoStage;
    private float logoAlpha;
    private long logoTime;
    private Sprite logo;
    private long logoSpeed;
    private ArrayList<Particle> p;
    private long pSpeed;
    private long pTime;
    private double p1x, p1y, p2x, p2y, p3x, p3y;
    private double pAng1, pAng2, pAng3;
    private int pSize;
    private int pSizeSpeed;
    private int pSizeGrow;
    private int pAlphaMax;

    public Intro(FullScreen fs, int numStars, long pSpeed, int pSize, int pSizeSpeed, int pSizeGrow, int pAlphaMax) {
        super(fs);

        rnd = new Random();

        // Setup the starfield.
        sf = new Starfield(numStars, 3000, 3000, 2000);
        sfAlpha = 0;
        sfTime = 25;
        sf.setAlpha(sfAlpha);
        sf.setSpeed(0.75);

        // Setup the logo.
        logo = new Sprite("hybris.png");
        logoAlpha = 0.0f;
        logoSpeed = 100;
        logoTime = logoSpeed;
        logoStage = 0;

        // Setup the particles. (Smoke-trails)
        p = new ArrayList<Particle>();
        this.pSpeed = pSpeed;
        pTime = pSpeed;
        this.pSize = pSize;
        this.pSizeSpeed = pSizeSpeed;
        this.pSizeGrow = pSizeGrow;
        this.pAlphaMax = pAlphaMax;
        p1x = 0;
        p1y = 0;
        p2x = 0;
        p2y = 0;
        p3x = 0;
        p3y = 0;
        pAng1 = 0.0;
        pAng2 = 66.0;
        pAng3 = 99.0;
    }

    @Override
    public void update(long difTime) {
        updateTime(difTime);
        FullScreen fs = getFullScreen();
        switch (getStage()) {
            case 0:
                // Stage 0: Initial state.
                if (getTime() >= 500) {
                    nextStage();
                }
                break;
            case 1:
                // Stage 1: Fade stars in.
                if (getTime() >= 7500) {
                    nextStage();
                }
                break;
            case 2:
                // Stage 2: Fade logo in and out.
                break;
            case 3:
                // Stage 3: Pause between logo and smoke-trails.
                if (getTime() >= 19500) {
                    nextStage();
                }
                break;
            case 4:
                // Stage 4: Smoke-trails.
                if (getTime() >= 50000) {
                    nextStage();
                }
                break;
            case 5:
                // Stage 5: Delay.
                if (getTime() >= 52500) {
                    nextStage();
                }
                break;
            case 6:
                // Stage 6: Fade starfield out.
                if (sfAlpha <= 0) {
                    stop();
                }
        }
        // Update the starfields movement.
        if (getStage() < 7) {
            sf.update(difTime);
        }

        if (getStage() == 1) {
            // Fade in the starfield.
            if (sfAlpha < 254) {
                sfTime -= difTime;
                if (sfTime <= 0) {
                    sfTime += 25;
                    sfAlpha += 1;
                    if (sfAlpha >= 255) {
                        sfAlpha = 255;
                    }
                    sf.setAlpha(sfAlpha);
                }
            }
        }

        if (getStage() == 2) {
            // Show the logo.
            switch (logoStage) {
                case 0:
                    logoAlpha += 0.0005 * difTime;
                    if (logoAlpha >= 1.0f) {
                        logoAlpha = 1.0f;
                        logoTime = 1000;
                        logoStage++;
                    }
                    break;
                case 1:
                    logoTime -= difTime;
                    if (logoTime <= 0) {
                        logoStage++;
                    }
                    break;
                case 2:
                    logoAlpha -= 0.00025 * difTime;
                    if (logoAlpha <= 0.0f) {
                        logoAlpha = 0.0f;
                        logoStage++;
                    }
                    break;
                case 3:
                    nextStage();
                    break;
            }
        }

        // Stage 3: Waiting...

        // Update the smoke-trails that are left on the screen, even outside stage 4.
        if (p.size() > 0) {
            for (int i = 0; i < p.size(); i++) {
                p.get(i).update(difTime);
                if (!p.get(i).isActive()) {
                    p.remove(i);
                }
            }
        }
        if (getStage() == 4) {
            // Update the smoke-trails.
            pAng1 += 0.1 * difTime;
            if (pAng1 >= 360.0) {
                pAng1 -= 360.0;
            }
            pAng2 += 0.06666 * difTime;
            if (pAng2 >= 360.0) {
                pAng2 -= 360.0;
            }
            pAng3 += 0.05454 * difTime;
            if (pAng3 >= 360.0) {
                pAng3 -= 360.0;
            }
            p1x = Math.cos(Math.toRadians(pAng1)) * (fs.getWidth2() / 1.5) + fs.getWidth2();
            p1y = Math.sin(Math.toRadians(pAng2)) * (fs.getHeight2() / 2) + fs.getHeight2() + fs.getHeight()/6;
            p2x = Math.cos(Math.toRadians(pAng2)) * (fs.getWidth2() / 1.5) + fs.getWidth2();
            p2y = Math.sin(Math.toRadians(pAng1)) * (fs.getHeight2() / 2) + fs.getHeight2() + fs.getHeight()/6;
            p3x = Math.cos(Math.toRadians(pAng3)) * (fs.getWidth2() / 1.5) + fs.getWidth2();
            p3y = Math.sin(Math.toRadians(pAng3 * 2.0)) * (fs.getHeight2() / 2) + fs.getHeight2() + fs.getHeight()/6;
            pTime -= difTime;
            while (pTime <= 0) {
                pTime += pSpeed;
                p.add(new Particle((int) p1x, (int) p1y, rnd.nextDouble() * 3.0 - 1.5, -rnd.nextDouble() * 5.0 - 5.0, 0.0, 1000, new Color(255, 255, 0)));
                int pc1 = rnd.nextInt(3);
                if (pc1 == 0) {
                    p.get(p.size() - 1).setColor(new Color(255, 255, 0));
                }
                if (pc1 == 1) {
                    p.get(p.size() - 1).setColor(new Color(127, 127, 0));
                }
                if (pc1 == 2) {
                    p.get(p.size() - 1).setColor(new Color(63, 63, 0));
                }
                p.get(p.size() - 1).setSize(pSize);
                p.get(p.size() - 1).setSizeSpeed(pSizeSpeed);
                p.get(p.size() - 1).setSizeGrow(pSizeGrow);
                p.get(p.size() - 1).setAlphaMax(pAlphaMax);
                p.add(new Particle((int) p2x, (int) p2y, rnd.nextDouble() * 3.0 - 1.5, -rnd.nextDouble() * 5.0 - 5.0, 0.0, 1000, new Color(0, 255, 255)));
                int pc2 = rnd.nextInt(3);
                if (pc2 == 0) {
                    p.get(p.size() - 1).setColor(new Color(0, 255, 255));
                }
                if (pc2 == 1) {
                    p.get(p.size() - 1).setColor(new Color(0, 127, 127));
                }
                if (pc2 == 2) {
                    p.get(p.size() - 1).setColor(new Color(0, 63, 63));
                }
                p.get(p.size() - 1).setSize(pSize);
                p.get(p.size() - 1).setSizeSpeed(pSizeSpeed);
                p.get(p.size() - 1).setSizeGrow(pSizeGrow);
                p.get(p.size() - 1).setAlphaMax(pAlphaMax);
                p.add(new Particle((int) p3x, (int) p3y, rnd.nextDouble() * 3.0 - 1.5, -rnd.nextDouble() * 5.0 - 5.0, 0.0, 1000, new Color(rnd.nextInt(255), rnd.nextInt(255), rnd.nextInt(255))));
                int pc3 = rnd.nextInt(3);
                if (pc3 == 0) {
                    p.get(p.size() - 1).setColor(new Color(255, 0, 255));
                }
                if (pc3 == 1) {
                    p.get(p.size() - 1).setColor(new Color(127, 0, 127));
                }
                if (pc3 == 2) {
                    p.get(p.size() - 1).setColor(new Color(63, 0, 63));
                }
                p.get(p.size() - 1).setSize(pSize);
                p.get(p.size() - 1).setSizeSpeed(pSizeSpeed);
                p.get(p.size() - 1).setSizeGrow(pSizeGrow);
                p.get(p.size() - 1).setAlphaMax(pAlphaMax);
            }
        }

        if (getStage() == 6) {
            // Fade out the starfield.
            if (sfAlpha > 0) {
                sfTime -= difTime;
                if (sfTime <= 0) {
                    sfTime += 25;
                    sfAlpha -= 2;
                    if (sfAlpha <= 0) {
                        sfAlpha = 0;
                    }
                    sf.setAlpha(sfAlpha);
                }
            }
        }
    }

    @Override
    public void draw() {

        FullScreen fs = getFullScreen();
        
        Graphics g = fs.getGraphics();

        // Clear the screen to black.
        g.setColor(new Color(0, 0, 0));
        g.fillRect(0, 0, fs.getWidth(), fs.getHeight());

        if (sfAlpha > 0 && getStage() < 7) {
            // Draw the starfield.
            sf.draw(g, fs.getWidth(), fs.getHeight());
        }

        if (getStage() == 2) {
            // Draw the logo.
            if (logoStage < 3) {
                logo.setAlpha(logoAlpha);
                logo.draw(g, fs.getWidth2() - logo.getWidth() / 2, fs.getHeight2() - logo.getHeight() / 2);
            }
        }

        if (p.size() > 0) {
            // Draw the smoke-trails
            for (int i = 0; i < p.size(); i++) {
                p.get(i).draw(g, fs.getWidth(), fs.getWidth());
            }
        }
        if (getStage() == 4) {
            g.setColor(new Color(255, 255, 0));
            g.fillOval((int) p1x, (int) p1y, pSize, pSize);
            g.setColor(new Color(0, 255, 255));
            g.fillOval((int) p2x, (int) p2y, pSize, pSize);
            g.setColor(new Color(255, 0, 255));
            g.fillOval((int) p3x, (int) p3y, pSize, pSize);
        }

        // Copy what we have drawn to the front buffer.
        fs.show();

        // Dispose this graphics object. Important since we use a different buffer each frame.
        g.dispose();
    }
}
